﻿using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
using System.Windows.Interop;

using Aliphant.Interface.Form;
using Aliphant.Wallpaper.Net.Helpers;

using Microsoft.Win32;

using static Aliphant.Wallpaper.Net.Helpers.DllImpoter;

using Point = Aliphant.Datas.Point;
using Rect = Aliphant.Datas.Rect;

namespace Aliphant.Wallpaper.Net
{
    internal class WallpaperEngine : IWallpaper
    {
        private IntPtr FatherForm = IntPtr.Zero;
        private IntPtr Handle = IntPtr.Zero;

        public WallpaperEngine()
        {

        }

        public bool TopWindow(Window window)
        {
            try
            {
                DllImpoter.SetParent(new WindowInteropHelper(window).Handle, IntPtr.Zero);
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool SetWallpaper(Window window)
        {
            try
            {
                FatherForm = GetBackForm();
                if (FatherForm == IntPtr.Zero)
                {
                    return false;
                }
                else
                {
                    DllImpoter.SetParent(new WindowInteropHelper(window).Handle, FatherForm);
                    return true;
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void SetWallpaper(string path)
        {
            IntPtr ret = DllImpoter.SystemParametersInfoA((int)UIACTION.SPI_SETDESKWALLPAPER, 0, path, 1);
            //Debug.WriteLine(ret);
        }

        public bool GetForce(Window window)
        {
            try
            {
                if (Handle == IntPtr.Zero)
                {
                    WindowInteropHelper wndHelper = new WindowInteropHelper(window);
                    Handle = wndHelper.Handle;
                }
                if (Handle != DllImpoter.GetForegroundWindow())
                {
                    DllImpoter.SetForegroundWindow(Handle);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public void DoGetCursorPos(out Point point)
        {
            IntPtr result = DllImpoter.GetCursorPos(out Point tagPOINT);
            if (result.ToInt32() == 1)
            {
                point = tagPOINT;
            }
            else
            {
                point = new Point();
            }
        }

        public void DoSetCursorPos(int x, int y)
        {
            DllImpoter.SetCursorPos(x, y);
        }

        public void GetWindowPos(Window window, out Rect rect)
        {
            rect = new Rect();
            WindowInteropHelper wndHelper = new WindowInteropHelper(window);
            IntPtr result = DllImpoter.GetWindowRect(wndHelper.Handle, ref rect);
            if (result.ToInt32() != 1)
            {
                rect = new Rect();
            }
        }

        /// <summary>
        /// 获取背景层
        /// </summary>
        /// <returns></returns>
        public IntPtr GetBackForm()
        {
            IntPtr background = IntPtr.Zero;
            IntPtr father = DllImpoter.FindWindowA("progman", "Program Manager");   //找到图标层
            IntPtr workerW = IntPtr.Zero;
            do
            {
                workerW = DllImpoter.FindWindowExA(IntPtr.Zero, workerW, "workerW", null);
                if (workerW != IntPtr.Zero)
                {
                    char[] buff = new char[200];
                    IntPtr b = Marshal.UnsafeAddrOfPinnedArrayElement(buff, 0);
                    int ret = (int)DllImpoter.GetClassNameA(workerW, b, 400);
                    if (ret == 0) return IntPtr.Zero;
                }
                if (DllImpoter.GetParent(workerW) == father)
                {
                    background = workerW;
                }
            } while (workerW != IntPtr.Zero);
            return background;
        }

        /// <summary>
        /// 刷新壁纸
        /// </summary>
        /// <returns></returns>
        public bool RefreshBackground()
        {
            StringBuilder sb = new StringBuilder(200);
            DllImpoter.SystemParametersInfo((int)UIACTION.SPI_GETDESKWALLPAPER, 200, sb, 0);
            int ret = DllImpoter.SystemParametersInfo((int)UIACTION.SPI_SETDESKWALLPAPER, 1, sb, 3);
            if (ret != 0)
            {
                RegistryKey hk = Registry.CurrentUser;
                RegistryKey run = hk.CreateSubKey(@"Control Panel\Desktop\");
                run.SetValue("Wallpaper", sb.ToString());
                return true;
            }
            return false;
        }
    }
}
